﻿/*
 * Copyright 2012 Sensible Softwares Pvt. Ltd, India. (http://bootstraptoday.com)
 *
 * Licensed under the MIT License. (http://opensource.org/licenses/mit-license.php)
 *
*/
 
var special_key_map = { 'enter': 13, 'esc': 27}
ko.bindingHandlers.shortcut = {
	init: function(element, valueAccessor, allBindingsAccessor,viewModel) {
		var key = valueAccessor();
		key = key.toLowerCase();
		var match = key.match(/ctrl\+/gi);
		var ctrl_modifier = Boolean(match && match.length > 0);
		match = key.match(/alt\+/gi);
		var alt_modifier = Boolean(match && match.length > 0);
		key = key.replace(/(alt\+|ctrl\+)/gi,'');
		var keycode = null;
		if( key in special_key_map) {
			keycode = special_key_map[key];
		}else {
			keycode = key.charCodeAt(0);
		}
 
		// if no modifiers are specified in the shortcut (.e.g shortcut is just 'n')
		// in such cases, do not trigger the shortcut if the focus is on
		// form field.
		// if modifier are specified, then even if focus is on form field
		// trigger the shortcut (e.g. ctrl+enter)
		var ignore_form_input=Boolean(ctrl_modifier || alt_modifier || key in special_key_map);
 
		var handler = function(event) {
			//first check if the element is visible. Do not trigger clicks
			// on invisible elements. This way I can add short cuts on
			// drop down menus.
			var $element = $(element);
			var $target = $(event.target);
			var is_forminput = Boolean($target.is('button')==false && $target.is(':input')==true)
			if($element.is(':visible') && (ignore_form_input==true || is_forminput==false)) {
				var modifier_match = ( ctrl_modifier == (event.metaKey || event.ctrlKey))
                    && ( alt_modifier == event.altKey );
 
				if( modifier_match && (event.charCode == keycode || event.keyCode == keycode)) {
					event.preventDefault();
					event.stopPropagation();
					$element.click();
					// event is handled so return false so that any further propagation is stopped.
					return false;
				}
			}
			// event is not handled. Hence return true so that propagation continues.
			return true;
		}
 
		var eventname='keypress';
		if( key in special_key_map) {
			eventname = 'keydown';
		}
 
		$('body').on(eventname, handler);
 
		var removeHandlerCallback = function() {
			$('body').off(eventname, handler);
		}
 
		// Now add a callback on the element so that when the element is 'disposed'
		// we can remove the event handler from the 'body'
		ko.utils.domNodeDisposal.addDisposeCallback(element, removeHandlerCallback);
	}
}